<?php
/**
 * 食谱测评算法结论部分
 *
 * 有多选的就  第三级别  和 第四级别
 * 标签输出的顺序是　
 * 第一优先条件
 * LV1  >  LV2 >  LV3 > LV4
 * LV1(第2，5，16题)，能列出的最大标签数为3
 * LV2(第3，4，6题)，能列出的最大标签数为2 （bmi和作业环境题）
 *
 * 第二优先条件
 * 单个级别下 各个题目的总权值
 *
 * 第三优先条件
 * 单道题目中的 各个选项的权值
 * Created by PhpStorm.
 * User: liao
 * Date: 2016/12/12
 * Time: 16:41
 */

namespace App\Services\Result;

use App\Interf\Resultable;
use App\Models\LogHelper;
use ParamConfig;
use UserTagService;
use TestingConfig;

use Illuminate\Support\Facades\Redis;


class RecipeTestingResult extends BaseResult implements Resultable
{
    private $answers;

    private $tabAttr;

    private $firstLevelAnswers = [] ;
    private $secondLevelAnswers  = [];
    private $thirdLevelAnswers = [] ;
    private $fourthLevelAnswers = [] ;

    private $userTag = [];

    private $bmiIndex ;

    const MAX_TAG_NUM = 4;

    const SPLIT_STR = "<br>";


    public function __construct($uid,$tid,$answersStr = null,$score = null)
    {
        $this->uid = $uid;
        $this->tid = $tid;
        $this->answers = $this->convertAnswer($answersStr);
        $this->tabAttr = $this->configAttrObj(1,'测评结果');
        $this->firstLevelIndex = [2,5,16];
        $this->secondLevelIndex = [3,4,6];
        $this->thirdLevelIndex = [7,8,9,10,11,12,13,14,15,16];
        $this->fourthLevelIndex = [17,18,19,20,21,22];
        $this->bmiIndex = 23;
        $this->initLevelAnswers();
        //食谱redis缓存数据库编号
        $this->recipeRedisIndex = ParamConfig::getValue('recipe.redis.index',9,true);

        $this->tagCssBody = ParamConfig::getValue('testing.recipe.result.css.body');

        $this->tagCss =ParamConfig::getValue('testing.recipe.result.css.single.lable');
        //没有tag时候的显示样式
        $this->noTagCss =ParamConfig::getValue('testing.recipe.result.css.no.tag');

    }


    public function result()
    {
        $attrs = [];
        /*健康状态*/
        array_push($attrs,$this->getTabAttr());
        //一下三个参数都是必须的
        $data['attrs'] = $attrs;
        $data['chatparam'] = $this->getChatparam();
        $data['chatType'] = $this->getChatType();
        return $data;

    }


    /**
     * 健康状态
     */
    protected function getTabAttr(){
        $note = '';
        //获取额外部分
        $extra = '';
        $obj = $this->tabAttr;
        $this->getTabNote($note);
        $obj = $this->compactAttrObj($obj['attr_id'],$obj['title'],$note,$extra);
        return $obj;
    }


    /**
     * 获取图表的类型
     */
    public function getChatType($type = 'gauge')
    {
        return "";
    }



    /**
     * 图标对应的BMI数据
     */
    protected function getChatparam(){
        $data = [];
        return $data;
    }



    protected function getTabNote(&$note = ''){

        //计算第一等级的标签
        $firstLevelData = $this->getLevelTag(1,$this->firstLevelAnswers);
        $firstLevelCount = $firstLevelData['tagCount'];
        if($firstLevelCount >=self::MAX_TAG_NUM){
            //如果tag数量大于 当前剩余的tag数据，取$leftCount个tag
            $this->getLeftDataNote($note,$firstLevelCount,$firstLevelData['data']);
            return;
        }
        //如果tag数量大于 当前剩余的tag数据
        $this->compactNote($note,$firstLevelData['data']);

        //计算第二等级的标签
        $leftCount = self::MAX_TAG_NUM - $firstLevelCount;
        $secondLevelData = $this->getLevelTag(2,$this->secondLevelAnswers);
        $secondLevelCount = $secondLevelData['tagCount'];
        //为0的情况，检查bmi是否正常
        if($secondLevelCount == 0){
            //获取bmi对应的tag
            $this->getBmiTag($note,$leftCount);
        }else{
            if($secondLevelCount >= $leftCount){
                //如果tag数量大于 当前剩余的tag数据，取$leftCount个tag
                $this->getLeftDataNote($note,$leftCount,$secondLevelData['data']);
                return;
            }
            //如果tag数量大于 当前剩余的tag数据
            $this->compactNote($note,$secondLevelData['data']);
            $leftCount = $leftCount -  $secondLevelCount;
            $this->getBmiTag($note,$leftCount);
        }


        //计算第三等级的标签
        $thirdLevelData = $this->getLevelTag(3,$this->thirdLevelAnswers);
        $thirdLevelCount = $thirdLevelData['tagCount'];
        if($thirdLevelCount >= $leftCount){
            //如果tag数量大于 当前剩余的tag数据，取$leftCount个tag
            $this->getLeftDataNote($note,$leftCount,$thirdLevelData['data']);
            return;

        }
        //如果tag数量大于 当前剩余的tag数据
        $this->compactNote($note,$thirdLevelData['data']);


        //计算第四等级的标签
        $leftCount = $leftCount -  $thirdLevelCount;
        $fourthLevelData = $this->getLevelTag(4,$this->fourthLevelAnswers);
        $fourLevelCount = $fourthLevelData['tagCount'];
        $this->getLeftDataNote($note,$leftCount,$fourthLevelData['data']);
//        if($fourLevelCount >= $leftCount){
//            //如果tag数量大于 当前剩余的tag数据，取$leftCount个tag
//            $this->getLeftDataNote($note,$leftCount,$fourthLevelData['data']);
//            return;
//        }
//
//        $this->compactUserTagStyle($note);
//        //最后都进行保存操作
//        $this->saveTagsToDb();

    }

    /**
     * 获取剩余的tag描述部分
     * @param string $note
     * @param Number $leftCount
     * @param array $levelData
     */
    protected function getLeftDataNote(&$note,$leftCount,$inputLevelData){
        //如果tag数量大于 当前剩余的tag数据，取$leftCount个tag
        $tags = $this->calculateTags($leftCount,$inputLevelData);
        $this->compactUserTagStyle($note);
        $this->saveTagsToDb();
        return $tags;
    }

    public function calculateTags($leftCount,$inputLevelData){
        $tags = [];
        $count = 0;
        foreach ($inputLevelData as $d){
            //先将option的值按照weight进行排序
            $options = $d['options'];
            arsort($options);
            foreach ($options as $opt){
                if($count < $leftCount){
                    $optTags = $opt['tag'];
                    foreach ($optTags as $ot){
                        if(!in_array($ot,$this->userTag)){
                            array_push($tags,$ot);
                            array_push($this->userTag,$ot);
                            $count ++;
                        }
                    }
                }

            }
        }
        return $tags;
    }


    protected function getBmiTag(&$note,&$leftCount){
        if($leftCount > 0){
            $bmiAnswer = $this->getAnswerObjByIndex($this->answers,$this->bmiIndex);
            $bmi = $bmiAnswer['weight'];
            $bmiTag = '';
            if($bmi >= 24 ){
                $bmiTag = '减肥瘦身食谱';
            }else if($bmi<18.5){
                $bmiTag = '营养不良食谱';
            }

            $bmiData = [];
            if($bmiTag){
                $bmiAnswer['tag'] = (array)$bmiTag;
                array_push($bmiData,$bmiAnswer);
                $this->compactNote($note,$bmiData);
                $leftCount--;
            }
        }
    }

    /**
     * 数据库中存的css样式为：
     * <div class="label label{{LABEL_INDEX}}  {{FIRST_LABER_CSS}}"><span>{{TAG_CONTENT}}</span></div>
     * css body 为
     * <div class="recipe_label">{{SUB_LABELS}}</div>
     *
     */

    protected function compactUserTagStyle(&$note){
        $userTags = $this->userTag;
        $count = count($userTags);
        $tagCssStyle = "";
        if($count > 0){
            $note .= ParamConfig::getValue('testing.recipe.result.title');
            $tagCount = 1;
            $firstLabel = $count == 1 ? 'labelfirst' : "";
            foreach ($this->userTag as $tag){
                $cssStyle = str_replace('{{LABEL_INDEX}}',$tagCount,$this->tagCss);
                $cssStyle = str_replace('{{FIRST_LABER_CSS}}',$firstLabel,$cssStyle);
                $cssStyle = str_replace('{{TAG_CONTENT}}',$tag,$cssStyle);
                $tagCssStyle .= $cssStyle;
                LogHelper::log($cssStyle);
                LogHelper::log($tagCssStyle);
                $tagCount++;
            }
            $tagCssStyle = str_replace('{{SUB_LABELS}}',$tagCssStyle,$this->tagCssBody);
            $note .= $tagCssStyle;
            //增加提示部分
            $clickHintStyle = ParamConfig::getValue('testing.recipe.result.user.guide','<div class="notetxt">点击下方“确定”进入您的个性食谱</div>');
            $note .= $clickHintStyle;
            LogHelper::log('final tag style====>'.$tagCssStyle);
        }else{
            $note .= $this->noTagCss;
        }


    }


    protected function saveTagsToDb(){
        //首先清除最新的tag
        $cacheKey = getCacheKey('testing.cache_key.testing_user_tag.latest_tag_info') . $this->tid.'_'.$this->uid;
        UserTagService::forget($cacheKey);
        $this->clearRecipeUserTag();
        $data = [
            'uid' => $this->uid,
            'tid' => $this->tid,
            'tag' => implode('|',$this->userTag),
        ];
        UserTagService::store($data);
    }


    /**
     * 删除食谱中用户最近的tag
     * @param string $note
     * @param array $levelData
     */
    protected function clearRecipeUserTag(){
//        $cacheKey = TestingConfig::getValue('recipe.redis.cache.user.latest.tag','USER_LATEST_TAG_',true).$this->uid;
//        Redis::select($this->recipeRedisIndex);
//        UserTagService::forget($cacheKey);
        $userTagCacheUrl = TestingConfig::getValue('recipe.url.clear.user.tag','',true);
        $userTagCacheUrl = str_replace('{uid}',$this->uid,$userTagCacheUrl);
        curlRequest($userTagCacheUrl);
    }

    /**
     * 组装描述部分
     * @param string $note
     * @param array $levelData
     */
    protected function compactNote(&$note,$levelData){
        if(count($levelData)>0){
            $tags = [];
            foreach ($levelData as $d){
                foreach ($d['tag'] as $tag){
                    if(!in_array($tag,$this->userTag)){
                        array_push($tags,$tag);
                        array_push($this->userTag,$tag);
                    }
                }
            }
//            $note .= implode(self::SPLIT_STR,$tags).self::SPLIT_STR;
        }
    }


    /**
     * 获取剩余的tag描述部分
     * @param Number $level
     * @param array $levelAnswers
     * @return array
     */
    protected function getLevelTag($level,$levelAnswers){
        $data = [];
        $tags = $this->getOriginLevelTag($level);
        $totalTag = 0;
        if (count($tags) > 0) {
            //先遍历提交的答案
            foreach ($levelAnswers as $answer) {
                $tagCount = 0;
                //多选题
                $options = explode('|||',$answer['answer']);
                //每个答案对应的选项列表，选项中包含 name 、weight、和对应的tag
                $optionDataList = [];
                //答案的总tag
                $answerTags = [];
                foreach ($options as $answerOpt){
                    foreach ($tags as $tag) {
                        $key = $tag['key'];
                        $arr = explode('|',$key);
                        $option = $arr[0];
                        $answerIndex = $arr[1];
                        $singleOptionWeight = $arr[2];
                        if($answerOpt == $option){
                            $tagArr = explode('|',$tag['value']);
                            $answer['tag'] = $tagArr;
                            $tagCount = $tagCount + count($tagArr);
                            $totalTag = $totalTag + count($tagArr);
                            $singleOpt = [];
                            $singleOptTag = [];
                            foreach ($tagArr as $tag){
                                array_push($answerTags,$tag);
                                array_push($singleOptTag,$tag);
                            }
                            $singleOpt['weight'] = $singleOptionWeight;
                            $singleOpt['tag'] = $singleOptTag;
                            $singleOpt['name'] = $answerOpt;
                            array_push($optionDataList,$singleOpt);
                            break;
                        }
                    }
                }

                $answer['tag'] = $answerTags;
                $answer['tagCount'] = $tagCount;
                $answer['options'] = $optionDataList;
                array_push($data,$answer);
            }
        }

        $result['data'] = $data;
        $result['tagCount'] = $totalTag;
        return $result;
    }


    /**
     * 从数据库中根据level参数查询对应的tag
     * @param Number $level
     * @return array
     */
    protected function getOriginLevelTag($level){
        $tag = 'RT.level.'.$level;
        $tags = ParamConfig::getByTag($tag);
        return $tags;
    }

    /**
     * 初始化各个分级的答案
     */
    protected function initLevelAnswers(){
        foreach ($this->answers as $answer){
            $obj = [];
            if(in_array($answer['index'],$this->firstLevelIndex)){
                array_push($this->firstLevelAnswers,$answer);
            }
            if(in_array($answer['index'],$this->secondLevelIndex)){
                array_push($this->secondLevelAnswers,$answer);
            }
            if(in_array($answer['index'],$this->thirdLevelIndex)){

                $obj['weight'] = $answer['weight'];
                $obj['index'] = $answer['index'];
                $obj['answer'] = $answer['answer'];
                array_push($this->thirdLevelAnswers,$obj);
            }
            if(in_array($answer['index'],$this->fourthLevelIndex)){
                $obj['weight'] = $answer['weight'];
                $obj['index'] = $answer['index'];
                $obj['answer'] = $answer['answer'];
                array_push($this->fourthLevelAnswers,$obj);
            }
        }
        //按照权值来将第三等级和第四等级的答案进行排序
        arsort($this->thirdLevelAnswers);
        arsort($this->fourthLevelAnswers);
    }


}